import { ComponentSchema } from '@farris/designer-element';
import { DesignViewModelService, DomService, RefreshFormService } from '@farris/designer-services';
import { NotifyService } from '@farris/ui-notify';
import { RowNode } from '@farris/ui-treetable';
import { cloneDeep } from 'lodash-es';
import { ControlContextMenuItem } from '../../../../../entity/control-context-menu';
import { DgControl } from '../../../../../utils/dg-control';
import FarrisDesignField from '../component/field';
import { contextMenu } from './context-menu.config';

const MOVETO_COMMAND = 'moveTo';

export class InputsContextMenuService {


    /** form组件实例 */
    private cmpInstance: FarrisDesignField;

    /** 操作表单DOM的工具类 */
    private domService: DomService;

    /** 操作表单设计时ViewModel的工具类 */
    private dgVMService: DesignViewModelService;

    private notifyService: NotifyService;

    private refreshFormService: RefreshFormService;


    constructor(cmp: FarrisDesignField) {
        this.cmpInstance = cmp;

        const serviceHost = cmp.options.designerHost;
        const injector = serviceHost.getService('Injector');

        this.domService = serviceHost.getService('DomService');
        this.dgVMService = serviceHost.getService('DesignViewModelService');
        this.refreshFormService = serviceHost.getService('RefreshFormService');
        this.notifyService = injector.get(NotifyService);
    }


    /**
     * 组装【移动至】菜单
     * @param controlNode 控件dom
     * @param menuConfig 菜单配置
     */
    setContextMenuConfig() {
        let menuConfig = cloneDeep(contextMenu) as ControlContextMenuItem[];
        if (!menuConfig) {
            return [];
        }
        const moveToMenu = menuConfig.find(menu => menu.id === MOVETO_COMMAND);
        if (!moveToMenu) {
            return menuConfig;
        }


        const formComponent = this.domService.getComponentById(this.cmpInstance.componentId);
        const formNode = this.domService.selectNode(formComponent, item => item.type === DgControl.Form.type);
        if (!formNode) {
            // console.log('未检测到Form控件');
            menuConfig = menuConfig.filter(menu => menu.id !== MOVETO_COMMAND);
            return menuConfig;
        }

        const binding = this.cmpInstance.component.binding;
        const viewModel = this.domService.getViewModelById(formComponent.viewModel);
        const viewModelField = viewModel.fields.find(field => field.id === binding.field);
        if (!binding || !viewModelField) {
            // console.log('控件没有绑定信息，不支持移动');
            menuConfig = menuConfig.filter(menu => menu.id !== MOVETO_COMMAND);
            return menuConfig;
        }

        // 分组内控件，只能移动至分组外，即component下
        if (viewModelField.groupId) {
            moveToMenu.children = [{
                title: '卡片面板',
                id: formNode.id,
                controlType: DgControl.Form.type,
                parentMenuId: 'moveTo',
                handle: (e) => { this.contextMenuClicked(e); }
            }];
        } else {
            // 分组外控件，可以移动至分组内，即Form下所有的FieldSet节点内
            const fieldSetNodes = formNode.contents.filter(node => node.type === DgControl.FieldSet.type);
            if (fieldSetNodes.length > 0) {
                moveToMenu.children = [];
                fieldSetNodes.forEach(fieldSet => {
                    moveToMenu.children.push({
                        title: fieldSet.title,
                        id: fieldSet.id,
                        parentMenuId: 'moveTo',
                        controlType: DgControl.FieldSet.type,
                        handle: (e) => { this.contextMenuClicked(e); }
                    });
                });
            } else {
                // console.log('当前面板中没有分组，不支持移动');
                menuConfig = menuConfig.filter(menu => menu.id !== MOVETO_COMMAND);
                return menuConfig;
            }

        }

        return menuConfig;

    }

    /**
     * 点击控件树右键菜单
     */
    private contextMenuClicked(e: { data: RowNode, menu: ControlContextMenuItem }) {

        const menu = e.menu;

        switch (menu.parentMenuId) {
            // 移动至
            case 'moveTo': {
                this.moveControlTo(this.cmpInstance.component, menu);
                break;
            }
            default: {
                this.notifyService.warning('暂不支持');
            }
        }
    }


    /**
     * 移动至
     * @param dgControlNode 控件元素
     * @param menuItem 菜单
     */
    private moveControlTo(controlNode: ComponentSchema, menuItem: ControlContextMenuItem) {
        const targetControlType = menuItem.controlType;
        const targetControlId = menuItem.id;

        const formComponent = this.domService.getComponentById(this.cmpInstance.componentId);
        const formNode = this.domService.selectNode(formComponent, item => item.type === DgControl.Form.type);

        const dgVM = this.dgVMService.getDgViewModel(this.cmpInstance.viewModelId);

        switch (targetControlType) {
            // 从分组内移动至分组外
            case DgControl.Form.type: {

                dgVM.changeField(controlNode.binding.field, { groupId: null, groupName: null });

                const currentFieldSetNode = this.cmpInstance.parent.component;
                currentFieldSetNode.contents = currentFieldSetNode.contents.filter(c => c.id !== controlNode.id);

                formNode.contents.push(controlNode);

                // 若分组下没有控件了，需要移除分组
                if (currentFieldSetNode.contents.length === 0) {
                    formNode.contents = formNode.contents.filter(c => c.id !== currentFieldSetNode.id);
                }
                break;
            }
            // 从分组外移动至分组内
            case DgControl.FieldSet.type: {
                const targetFieldSetNode = this.domService.domDgMap.get(targetControlId);
                targetFieldSetNode.contents.push(controlNode);

                dgVM.changeField(controlNode.binding.field, { groupId: targetControlId, groupName: targetFieldSetNode.title });

                formNode.contents = formNode.contents.filter(c => c.id !== controlNode.id);
                break;
            }
        }

        this.notifyService.success('移动成功');
        this.refreshFormService.refreshFormDesigner.next(formNode.id);
    }
}
